//
// Created by 12992 on 24-10-1.
//

#include "media_frame.h"
#include <iostream>
#include <utility>

extern "C" {
#include <libavcodec/avcodec.h>
}

namespace utils
{
    using namespace std;

    media_frame::media_frame(AVFrame* frame)
        : m_frame(av_frame_alloc())
    {
        if (!this->m_frame)
        {
            throw runtime_error("can not alloc frame");
        }
        if (av_frame_ref(this->m_frame, frame) < 0)
        {
            av_frame_free(&this->m_frame);
            throw runtime_error("can not ref frame!");
        }
    }

    media_frame::media_frame(const media_frame& frame)
        : m_frame(av_frame_alloc())
    {
        if (!this->m_frame)
        {
            throw runtime_error("can not alloc frame");
        }
        if (av_frame_ref(this->m_frame, frame.m_frame) < 0)
        {
            av_frame_free(&this->m_frame);
            throw runtime_error("can not ref frame!");
        }
    }

    media_frame::media_frame(media_frame&& frame) noexcept
        : m_frame(exchange(frame.m_frame, nullptr))
    {
    }

    media_frame& media_frame::operator=(const media_frame& frame)
    {
        auto copy_obj = frame;
        swap(*this, copy_obj);
        return *this;
    }

    media_frame& media_frame::operator=(media_frame&& frame) noexcept
    {
        this->m_frame = exchange(frame.m_frame, nullptr);
        return *this;
    }

    media_frame::~media_frame()
    {
        av_frame_free(&this->m_frame);
    }

    AVFrame* media_frame::get_frame()
    {
        return this->m_frame;
    }

    media_frame::operator bool() const noexcept
    {
        return this->m_frame;
    }
} // utils
